<template>
    <!-- 增加on-clear方法 -->
    <div :class="wrapClasses" @mouseenter.stop="handleInputMouseenter" @mouseleave.stop="handleInputMouseleave">
        <input style="display: none !important;" :type="type" v-if="name && type !== 'textarea'" :name="name" v-model="currentValue">
        <textarea style="display: none !important;" v-if="name && type === 'textarea'" :name="name">{{currentValue}}</textarea>
        <template v-if="type !== 'textarea'">
            <div :class="[prefixCls + '-group-prepend']" v-if="prepend" v-show="slotReady">
                <slot name="prepend"></slot>
            </div>
            <!-- 增加on-clear方法 -->
            <i class="ivu-icon" :class="['ivu-icon-' + iconType, prefixCls + '-icon', prefixCls + '-icon-normal']" :style="{ right: iconRight}" v-if="iconShow" @click="handleIconClick"></i>
            <transition name="fade">
                <i class="ivu-icon ivu-icon-load-c ivu-load-loop" :class="[prefixCls + '-icon', prefixCls + '-icon-validate']" :style="{ right: iconRight + 'px' }" v-if="!icon"></i>
            </transition>
            <input
                    :type="type"
                    :class="inputClasses"
                    :placeholder="placeholder"
                    :disabled="disabled"
                    :maxlength="maxlength"
                    :readonly="readonly"
                    :value="currentValue"
                    :number="number"
                    :autofocus="autofocus"
                    @keyup.enter="handleEnter"
                    @focus="handleFocus"
                    @blur="handleBlur"
                    @input="handleInput"
                    @change="handleChange">
            <div :class="[prefixCls + '-group-append']" v-if="append" v-show="slotReady" ref="appendDiv">
                <slot name="append"></slot>
            </div>
        </template>
        <textarea
                v-else
                ref="textarea"
                :class="textareaClasses"
                :style="textareaStyles"
                :placeholder="placeholder"
                :disabled="disabled"
                :rows="rows"
                :maxlength="maxlength"
                :readonly="readonly"
                :value="currentValue"
                @keyup.enter="handleEnter"
                @focus="handleFocus"
                @blur="handleBlur"
                @input="handleInput">
        </textarea>
    </div>
</template>
<script>
    import {oneOf, findComponentUpward} from '../../utils/assist';
    import calcTextareaHeight from '../../utils/calcTextareaHeight';
    import Emitter from '../../mixins/emitter';

    const prefixCls = 'ivu-input';

    export default {
        name: 'Input',
        mixins: [Emitter],
        props: {
            type: {
                validator (value) {
                    return oneOf(value, ['text', 'textarea', 'password']);
                },
                default: 'text'
            },
            name: String,
            value: {
                type: [String, Number],
                default: ''
            },
            size: {
                validator (value) {
                    return oneOf(value, ['small', 'large']);
                }
            },
            placeholder: {
                type: String,
                default: ''
            },
            maxlength: {
                type: Number
            },
            disabled: {
                type: Boolean,
                default: false
            },
            clearable: {
                type: Boolean,
                default: true
            },
            editable: {
                type: Boolean,
                default: null
            },
            icon: String,
            autosize: {
                type: [Boolean, Object, Number, String],
                default: false
            },
            rows: {
                type: Number,
                default: 2
            },
            readonly: {
                type: Boolean,
                default: false
            },
            name: {
                type: String
            },
            number: {
                type: Boolean,
                default: false
            },
            autofocus: {
                type: Boolean,
                default: false
            }
        },
        data () {
            return {
                currentValue: this.value,
                prefixCls: prefixCls,
                prepend: true,
                append: true,
                showClose: false,
                slotReady: false,
                iconShow: true,//增加on-clear方法
                clearIcon: false,//增加on-clear方法
                textareaStyles: {},
                iconRight: 0
            };
        },
        computed: {
            //增加on-clear方法
            iconType () {
                if (this.showClose) {
                    this.clearIcon = true;
                    this.iconShow = true;
                    return 'ios-close';
                } else if (this.icon) {
                    this.iconShow = true;
                }
                this.clearIcon = false;
                return this.icon;
            },
            wrapClasses () {
                return [
                    `${prefixCls}-wrapper`,
                    {
                        [`${prefixCls}-wrapper-${this.size}`]: !!this.size,
                        [`${prefixCls}-type`]: this.type,
                        [`${prefixCls}-group`]: this.prepend || this.append,
                        [`${prefixCls}-group-${this.size}`]: (this.prepend || this.append) && !!this.size,
                        [`${prefixCls}-group-with-prepend`]: this.prepend,
                        [`${prefixCls}-group-with-append`]: this.append
                    }
                ];
            },
            inputClasses () {
                return [
                    `${prefixCls}`,
                    {
                        [`${prefixCls}-${this.size}`]: !!this.size,
                        [`${prefixCls}-disabled`]: this.disabled
                    }
                ];
            },
            textareaClasses () {
                return [
                    `${prefixCls}`,
                    {
                        [`${prefixCls}-disabled`]: this.disabled
                    }
                ];
            }
        },
        methods: {
            handleEnter (event) {
                this.$emit('on-enter', event);
            },
            handleIconClick (event) {
                //增加on-clear方法
                if (this.clearIcon) {
                    this.showClose = false;
                    this.currentValue = '';
                    this.$emit('on-clear');
                    event.stopPropagation();
                } else {
                    this.$emit('on-click', event);
                }
            },
            handleFocus (event) {
                this.$emit('on-focus', event);
            },
            handleBlur (event) {
                this.$emit('on-blur', event);
                if (!findComponentUpward(this, ['DatePicker', 'TimePicker', 'Cascader', 'Search'])) {
                    this.dispatch('FormItem', 'on-form-blur', this.currentValue);
                }
            },
            handleInput (event) {
                let value = event.target.value;
                if (this.number) value = Number.isNaN(Number(value)) ? value : Number(value);
                this.$emit('input', value);
                this.setCurrentValue(value);
                this.$emit('on-change', event);
            },
            handleChange (event) {
                this.$emit('on-input-change', event);
            },
            setCurrentValue (value) {
                if (value === this.currentValue) return;
                this.$nextTick(() => {
                    this.resizeTextarea();
                });
                this.currentValue = value;
                if (!findComponentUpward(this, ['DatePicker', 'TimePicker', 'Cascader', 'Search'])) {
                    this.dispatch('FormItem', 'on-form-change', value);
                }

                if (this.editable == null) {//日期框等类型设置值的时候不显示清空按钮，因为当前输入框未获得焦点
                    if (this.clearable && value) {
                        this.showClose = true;
                    }
                }
            },
            resizeTextarea () {
                const autosize = this.autosize;
                if (!autosize || this.type !== 'textarea') {
                    return false;
                }

                const minRows = autosize.minRows;
                const maxRows = autosize.maxRows;

                this.textareaStyles = calcTextareaHeight(this.$refs.textarea, minRows, maxRows);
            },
            handleInputMouseenter () {//增加on-clear方法
                if (this.editable == null) {
                    if (this.readonly || this.disabled)return;
                } else {//日期选择框等类型，只要没有禁用则判断是否显示清空按钮
                    if (!this.editable || this.disabled)return;
                }

                if (this.clearable && this.currentValue) {
                    this.showClose = true;
                }
            },
            handleInputMouseleave () {//增加on-clear方法
                this.showClose = false;
            }
        },
        watch: {
            value (val) {
                this.setCurrentValue(val);
            }
        },
        mounted () {
            if (this.type !== 'textarea') {
                this.prepend = this.$slots.prepend !== undefined;
                this.append = this.$slots.append !== undefined;
            } else {
                this.prepend = false;
                this.append = false;
            }
            this.slotReady = true;
            this.resizeTextarea();

            this.$nextTick(function () {
                if (this.append) {
                    const style = window.getComputedStyle(this.$refs.appendDiv);
                    this.iconRight = style.getPropertyValue("width");
                }
            });
        }
    };
</script>
